﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace GalaxyDefenderChaos
{
    public abstract class CModel : MyModel
    {
        public Vector3 Position { get; set; }
        public Vector3 Rotation { get; set; }
        public Vector3 Scale { get; set; }
        public Model Model { get; private set; }
        protected Matrix[] modelTransforms;
        protected GraphicsDevice graphicsDevice;

        protected BoundingSphere boundingSphere;

        float _speed;

        public float Speed
        {
            get { return _speed; }
            set { _speed = value; }
        }

        public BoundingSphere BoundingSphere
        {
            get
            {
                // No need for rotation, as this is a sphere
                Matrix worldTransform = Matrix.CreateScale(Scale)
                   * Matrix.CreateTranslation(Position);
                BoundingSphere transformed = boundingSphere;
                transformed = transformed.Transform(worldTransform);
                return transformed;
            }
        }

        private void buildBoundingSphere()
        {
            BoundingSphere sphere = new BoundingSphere(Vector3.Zero, 0);
            // Merge all the model's built in bounding spheres
            foreach (ModelMesh mesh in Model.Meshes)
            {
                BoundingSphere transformed = mesh.BoundingSphere.Transform(
           modelTransforms[mesh.ParentBone.Index]);
                sphere = BoundingSphere.CreateMerged(sphere, transformed);
            }
            this.boundingSphere = sphere;
        }

        public CModel(Model Model, Vector3 Position, Vector3 Rotation,
             Vector3 Scale, GraphicsDevice graphicsDevice)
        {
            this.Model = Model;
            modelTransforms = new Matrix[Model.Bones.Count];
            Model.CopyAbsoluteBoneTransformsTo(modelTransforms);
            buildBoundingSphere();
            this.Position = Position;
            this.Rotation = Rotation;
            this.Scale = Scale;
            this.graphicsDevice = graphicsDevice;

            _speed = 5;
        }

        public virtual void Draw(Matrix View, Matrix Projection)
        {
            // Calculate the base transformation by combining
            // translation, rotation, and scaling
            Matrix baseWorld = Matrix.CreateScale(Scale)
               * Matrix.CreateFromYawPitchRoll(
                 Rotation.Y, Rotation.X, Rotation.Z)
               * Matrix.CreateTranslation(Position);
            foreach (ModelMesh mesh in Model.Meshes)
            {
                Matrix localWorld = modelTransforms[mesh.ParentBone.Index]
                   * baseWorld;
                foreach (ModelMeshPart meshPart in mesh.MeshParts)
                {
                    BasicEffect effect = (BasicEffect)meshPart.Effect;
                    effect.World = localWorld;
                    effect.View = View;
                    effect.Projection = Projection;
                    effect.EnableDefaultLighting();
                }
                mesh.Draw();
            }
        }

        public override void Draw(GraphicsDevice graphicsDevice, Camera camera, GameTime gameTime)
        {
            Draw(camera.View, camera.Projection);
            base.Draw(graphicsDevice, camera, gameTime);
        }

        public virtual void ChaseObject(GameTime gameTime, CModel destination)
        {
            if (destination != null)
            {
                //Vector3 rotaterocket = destination.Position - this.Position;
                //rotaterocket.Normalize();
                //this.Position += rotaterocket * (float)gameTime.ElapsedGameTime.TotalMilliseconds * speed;

                double angle = Math.Atan2(this.Position.X - destination.Position.X,
                        this.Position.Z - destination.Position.Z);

                this.Rotation = new Vector3(0, (float)angle, 0);

                Matrix rotation = Matrix.CreateFromYawPitchRoll(Rotation.Y, Rotation.X, Rotation.Z);

                Position += Vector3.Transform(Vector3.Forward, rotation) * (float)gameTime.ElapsedGameTime.TotalMilliseconds * _speed;
            }
        }
    }
}
